/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package DAO;

import bean.Apoio;
import bean.Autor;
import bean.Colecao;
import bean.Editora;
import bean.Formato;
import bean.Idioma;
import bean.Instituicao;
import bean.Livro;
import bean.Tema;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author fernando
 */
public class LivroDao implements Serializable {

    private Conexao conexao;
    private PreparedStatement ps;
    private boolean sucess = false;

    public LivroDao() {
        this.conexao = new ConexaoPostgres();

    }

    public boolean cadastrarLivro(Livro livro, Colecao colecao) {
        sucess = false;

        try {
            System.out.println("Cadastro Livro: ");
            System.out.println("Titulo: " + livro.getTitulo());


            ps = conexao.getConnection().prepareStatement("INSERT INTO Obra(ano, issn_isbn, quantidade_paginas, id_colecao, id_editora,  id_formato,  cidade_publicacao, uf_publicacao, indice, titulo, id_idioma, tipo, link) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ");
            ps.setInt(1, livro.getAnoPublicacao());
            ps.setString(2, livro.getISSN_ISBN());
            ps.setInt(3, livro.getQuantidadePaginas());
            ps.setInt(4, colecao.getId());
            ps.setInt(5, livro.getEditora().getId());
            ps.setInt(6, livro.getFormato().getId());
            ps.setString(7, livro.getCidadePublicacao());
            ps.setString(8, livro.getUfPublicacao());
            ps.setString(9, livro.getIndice());
            ps.setString(10, livro.getTitulo());
            ps.setInt(11, livro.getIdioma().getId());
            ps.setString(12, "Livro");
            ps.setString(13, livro.getLink());
            ps.executeUpdate();
            conexao.closeConnection();

            livro = this.consultaLivro(livro, colecao);
            System.out.println(livro.getId());
            if ((livro.getId() != -1) && (livro.getId() != 0)) { //-1 indica que por algum motivo ao consultar não foi encontrado o livro

                Iterator i = livro.getApoios().iterator();
                while (i.hasNext()) {
                    ps = conexao.getConnection().prepareStatement("INSERT INTO obra_apoio(id_obra, id_apoio) VALUES (?, ?)  ");
                    ps.setInt(1, livro.getId());
                    Apoio apoio = (Apoio) i.next();
                    ps.setInt(2, apoio.getId());
                    ps.executeUpdate();
                    conexao.closeConnection();

                }

                i = livro.getAutores().iterator();
                int posicao = 1;
                while (i.hasNext()) {
                    ps = conexao.getConnection().prepareStatement("INSERT INTO obra_autor(id_obra, id_autor, posicao) VALUES (?, ?, ?)  ");
                    ps.setInt(1, livro.getId());
                    Autor autor = (Autor) i.next();
                    ps.setInt(2, autor.getId());
                    ps.setInt(3, posicao);
                    posicao++;
                    ps.executeUpdate();
                    conexao.closeConnection();

                }
                /*
                 i = livro.getIdiomas().iterator();
                 while(i.hasNext()){
                 ps = conexao.getConnection().prepareStatement("INSERT INTO obra_idioma(id_obra, id_idioma) VALUES (?, ?)  ");
                 ps.setInt(1, livro.getId());
                 Idioma idioma =(Idioma) i.next();
                 ps.setInt(2,idioma.getId());
                 ps.executeUpdate();
                    
                 }*/


                i = livro.getTemas().iterator();
                while (i.hasNext()) {
                    ps = conexao.getConnection().prepareStatement("INSERT INTO obra_tema(id_obra, id_tema) VALUES (?, ?)  ");
                    ps.setInt(1, livro.getId());
                    Tema tema = (Tema) i.next();
                    ps.setInt(2, tema.getId());
                    ps.executeUpdate();
                    conexao.closeConnection();

                }

            }

            sucess = true;

        } catch (SQLException ex) {
            conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
            return sucess;
        }

        conexao.closeConnection();
        return sucess;
    }

    public boolean alterarLivro(Livro livro, Colecao colecao) {



        sucess = false;

        try {
            System.out.println("Cadastro Livro: ");
            System.out.println("Titulo: " + livro.getTitulo());


            ps = conexao.getConnection().prepareStatement("UPDATE Obra SET ano = ?, issn_isbn = ?, quantidade_paginas = ?,  id_colecao = ?, id_editora = ?, id_formato = ?, cidade_publicacao = ?, uf_publicacao = ?, indice = ?, titulo = ?, id_idioma = ?, tipo = ?, link = ? WHERE id = ?");
            ps.setInt(1, livro.getAnoPublicacao());
            ps.setString(2, livro.getISSN_ISBN());
            ps.setInt(3, livro.getQuantidadePaginas());
            ps.setInt(4, colecao.getId());
            ps.setInt(5, livro.getEditora().getId());
            ps.setInt(6, livro.getFormato().getId());
            ps.setString(7, livro.getCidadePublicacao());
            ps.setString(8, livro.getUfPublicacao());
            ps.setString(9, livro.getIndice());
            ps.setString(10, livro.getTitulo());
            ps.setInt(11, livro.getIdioma().getId());
            ps.setString(12, "Livro");
            ps.setString(13, livro.getLink());
            ps.setInt(14, livro.getId());
          
            ps.executeUpdate();
            conexao.closeConnection();

            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_apoio WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();

            Iterator i = livro.getApoios().iterator();
            while (i.hasNext()) {
                ps = conexao.getConnection().prepareStatement("INSERT INTO obra_apoio(id_obra, id_apoio) VALUES (?, ?)  ");
                ps.setInt(1, livro.getId());
                Apoio apoio = (Apoio) i.next();
                ps.setInt(2, apoio.getId());
                ps.executeUpdate();
                conexao.closeConnection();

            }

            //Remove Todos os elementos para inserir o que se alterar
            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_autor WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();


            i = livro.getAutores().iterator();
            int posicao = 1;
            while (i.hasNext()) {
                ps = conexao.getConnection().prepareStatement("INSERT INTO obra_autor(id_obra, id_autor, posicao) VALUES (?, ?, ?)  ");
                ps.setInt(1, livro.getId());
                Autor autor = (Autor) i.next();
                ps.setInt(2, autor.getId());
                ps.setInt(3, posicao);
                ps.executeUpdate();
                conexao.closeConnection();
                posicao++;

            }
            /*
             i = livro.getIdiomas().iterator();
             while(i.hasNext()){
             ps = conexao.getConnection().prepareStatement("INSERT INTO obra_idioma(id_obra, id_idioma) VALUES (?, ?)  ");
             ps.setInt(1, livro.getId());
             Idioma idioma =(Idioma) i.next();
             ps.setInt(2,idioma.getId());
             ps.executeUpdate();
                    
             }*/

            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_tema WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();

            i = livro.getTemas().iterator();
            while (i.hasNext()) {
                ps = conexao.getConnection().prepareStatement("INSERT INTO obra_tema(id_obra, id_tema) VALUES (?, ?)  ");
                ps.setInt(1, livro.getId());
                Tema tema = (Tema) i.next();
                ps.setInt(2, tema.getId());
                ps.executeUpdate();
                conexao.closeConnection();

            }



            sucess = true;

        } catch (SQLException ex) {
            conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
            return sucess;
        }

        conexao.closeConnection();
        return sucess;
    }

    public boolean removerLivro(Livro livro) {
        sucess = false;
        try {


            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_autor WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();



            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_apoio WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();



            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra_tema WHERE id_obra = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();


            ps = conexao.getConnection().prepareStatement(" DELETE FROM obra WHERE id = ?");
            ps.setLong(1, (livro.getId()));
            ps.executeUpdate();
            conexao.closeConnection();






            sucess = true;
        } catch (SQLException ex) {
            ex.printStackTrace();
            conexao.closeConnection();
            return sucess;
        }

        conexao.closeConnection();
        return sucess;
    }

    public ArrayList<Tema> buscarTemasLivro(Livro livro) {
        ArrayList<Tema> temasObra = new ArrayList<Tema>();
        try {
            ps = conexao.getConnection().prepareStatement("SELECT t.id, t.tema FROM tema AS t, obra_tema AS ot, obra AS o "
                    + "WHERE o.id = ? AND o.id = ot.id_obra AND t.id = ot.id_tema;    ");
            ps.setInt(1, livro.getId());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Tema t = new Tema();
            while (rs.next()) {

                t.setId(rs.getInt("id"));
                t.setTema(rs.getString("tema"));


                temasObra.add(t);

                t = new Tema();

            }

        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(LivroDao.class.getName()).log(Level.SEVERE, null, ex);
        }

        this.conexao.closeConnection();
        return temasObra;
    }

    public ArrayList<Apoio> buscarApoiosLivro(Livro livro) {
        ArrayList<Apoio> apoiosObra = new ArrayList<Apoio>();
        try {
            ps = conexao.getConnection().prepareStatement("SELECT a.id, a.nome FROM apoio_formento AS a, obra_apoio AS oa, obra AS o "
                    + "WHERE o.id = ? AND o.id = oa.id_obra AND a.id = oa.id_apoio;   ");
            ps.setInt(1, livro.getId());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Apoio a = new Apoio();
            while (rs.next()) {

                a.setId(rs.getInt("id"));
                a.setNome(rs.getString("nome"));


                apoiosObra.add(a);

                a = new Apoio();

            }

        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(LivroDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.conexao.closeConnection();
        return apoiosObra;
    }

    public List<Autor> buscarAutoresLivro(Livro livro) {
        ArrayList<Autor> autoresObra = new ArrayList<Autor>();
        try {
            ps = conexao.getConnection().prepareStatement("SELECT a.id, a.restante_nome, a.ultimo_nome, a.id_instituicao, i.nome, i.estado, i.municipio, a.lattes "
                    + "FROM autor AS a, instituicao AS i, obra_autor AS oa, obra AS o "
                    + "WHERE o.id = ? AND o.id = oa.id_obra AND a.id = oa.id_autor AND a.id_instituicao = i.id Order By posicao ");
            ps.setInt(1, livro.getId());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Instituicao i = new Instituicao();
            Autor a = new Autor();
            while (rs.next()) {

                a.setId(rs.getInt("id"));
                a.setRestanteNome(rs.getString("restante_nome"));
                a.setUltimoNome(rs.getString("ultimo_nome"));
                a.setLattes(rs.getString("lattes"));
                i.setId(rs.getInt("id_instituicao"));
                i.setNome(rs.getString("nome"));
                i.setEstado(rs.getString("estado"));
                i.setMunicipio(rs.getString("municipio"));
                a.setInstituicaoAutor(i);

                autoresObra.add(a);

                a = new Autor();
                i = new Instituicao();
            }

        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(LivroDao.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.conexao.closeConnection();
        return autoresObra;

    }

    public List<Livro> listarLivros() {
        List<Livro> livros = new ArrayList<Livro>();
        try {
            System.out.println("Fui Executado: Livro Dao  - listarLivros");
            ps = conexao.getConnection().prepareStatement("SELECT o.id, o.ano, o.cidade_publicacao, o.uf_publicacao, o.issn_isbn, o.quantidade_paginas, o.id_colecao, o.link, c.titulo AS colecao_titulo,  o.id_editora, e.nome, o.id_formato, f.tipo AS formato_tipo , o.id_idioma, i.idioma, o.tipo AS obra_tipo, o.indice, o.titulo AS obra_titulo  "
                    + "FROM obra AS o, idioma AS i, formato AS f, editora as e, colecao AS c "
                    + "WHERE o.tipo = 'Livro' AND o.id_editora = e.id AND o.id_colecao = c.id AND o.id_formato = f.id AND o.id_idioma = i.id  ORDER BY o.titulo");
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Editora ed = new Editora();
            Formato f = new Formato();
            Idioma i = new Idioma();

            while (rs.next()) {
                Livro livro = new Livro();
                Colecao colecao = new Colecao();

                livro.setId(rs.getInt("id"));
                livro.setAnoPublicacao(rs.getInt("ano"));
                livro.setISSN_ISBN(rs.getString("issn_isbn"));
                livro.setQuantidadePaginas(rs.getInt("quantidade_paginas"));
                livro.setCidadePublicacao(rs.getString("cidade_publicacao"));
                livro.setUfPublicacao(rs.getString("uf_publicacao"));
                livro.setLink(rs.getString("link"));

                colecao.setId(rs.getInt("id_colecao"));
                colecao.setNomeColecao(rs.getString("colecao_titulo"));

                ed.setId(rs.getInt("id_editora"));
                ed.setNome(rs.getString("nome"));
                livro.setEditora(ed);

                f.setId(rs.getInt("id_formato"));
                f.setFormato(rs.getString("formato_tipo"));
                livro.setFormato(f);

                i.setId(rs.getInt("id_idioma"));
                i.setIdioma(rs.getString("idioma"));
                livro.setIdioma(i);


                livro.setTipo(rs.getString("obra_tipo"));
                livro.setIndice(rs.getString("indice"));
                livro.setTitulo(rs.getString("obra_titulo"));

                livro.setAutores((ArrayList) this.buscarAutoresLivro(livro));
                livro.setApoios(this.buscarApoiosLivro(livro));
                livro.setTemas(this.buscarTemasLivro(livro));

                livros.add(livro);
              



            }
        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
        }


        this.conexao.closeConnection();

        return livros;

    }
    
    public Livro buscarLivro(int id) {
        Livro livro = new Livro();
        try {
            System.out.println("Fui Executado: Livro Dao  - buscaLivro - id: " + id);
            ps = conexao.getConnection().prepareStatement("SELECT o.id, o.ano, o.cidade_publicacao, o.uf_publicacao, o.issn_isbn, o.quantidade_paginas, o.id_colecao, o.link, c.titulo AS colecao_titulo,  o.id_editora, e.nome, o.id_formato, f.tipo AS formato_tipo , o.id_idioma, i.idioma, o.tipo AS obra_tipo, o.indice, o.titulo AS obra_titulo" +  
            " FROM obra AS o, idioma AS i, formato AS f, editora as e, colecao AS c WHERE o.id = ? AND o.id_editora = e.id AND o.id_colecao = c.id AND o.id_formato = f.id AND o.id_idioma = i.id  ORDER BY o.titulo;");
            ps.setInt(1, id);
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();
            Editora ed = new Editora();
            Formato f = new Formato();
            Idioma i = new Idioma();
            
            if(rs.next()) {
                
                Colecao colecao = new Colecao();

                livro.setId(rs.getInt("id"));
                livro.setAnoPublicacao(rs.getInt("ano"));
                livro.setISSN_ISBN(rs.getString("issn_isbn"));
                livro.setQuantidadePaginas(rs.getInt("quantidade_paginas"));
                livro.setCidadePublicacao(rs.getString("cidade_publicacao"));
                livro.setUfPublicacao(rs.getString("uf_publicacao"));
                livro.setLink(rs.getString("link"));

                colecao.setId(rs.getInt("id_colecao"));
                colecao.setNomeColecao(rs.getString("colecao_titulo"));

                ed.setId(rs.getInt("id_editora"));
                ed.setNome(rs.getString("nome"));
                livro.setEditora(ed);

                f.setId(rs.getInt("id_formato"));
                f.setFormato(rs.getString("formato_tipo"));
                livro.setFormato(f);

                i.setId(rs.getInt("id_idioma"));
                i.setIdioma(rs.getString("idioma"));
                livro.setIdioma(i);


                livro.setTipo(rs.getString("obra_tipo"));
                livro.setIndice(rs.getString("indice"));
                livro.setTitulo(rs.getString("obra_titulo"));

                livro.setAutores((ArrayList) this.buscarAutoresLivro(livro));
                livro.setApoios(this.buscarApoiosLivro(livro));
                livro.setTemas(this.buscarTemasLivro(livro));

               
            }
        } catch (SQLException ex) {
            this.conexao.closeConnection();
            Logger.getLogger(InstituicaoDao.class.getName()).log(Level.SEVERE, null, ex);
        }


        this.conexao.closeConnection();

        return livro;

    }

    //int ano, String issn_isbn, int quantidadepaginas, int id_colecao, int id_editora, int id_formato,  String cidade_publicacao, String uf_publicacao, String indice, String titulo
    public Livro consultaLivro(Livro livro, Colecao colecao) {
        this.ps = null;

        try {
            System.out.println("Livro Dao - Consulta Livro - Titulo: " + livro.getTitulo());

            ps = conexao.getConnection().prepareStatement("Select id from obra where titulo = ? ");
            ps.setString(1, livro.getTitulo());
            ResultSet rs = ps.executeQuery();
            conexao.closeConnection();

            if (rs.next()) {
                System.out.println("Livro Dao - Descobrir id livro - Encontrado! = " + livro.getId());
                livro.setId(rs.getInt("id"));
                return livro;

            }
        } catch (SQLException ex) {
            conexao.closeConnection();
            return livro;

        }
        System.out.println("Livro Dao - Descobrir id livro - Não encontrou o livro!");

        livro.setId(-1); //-1 codigo para livro não encontrado!
        conexao.closeConnection();
        return livro;
    }
}
